//
//  DFCommandParser.m
//  dfCommandBuilder
//
//  Created by Tom Booth on 31/05/2009.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "DFCommandParser.h"


@interface DFCommandParser (PrivateMethods)

-(DFCommand*) handleCommand:(NSXMLElement*) command;
-(DFParameter*) handleParameter:(NSXMLElement*) param;
- (BOOL) boolifyString:(NSString*) string;

@end

NSInteger compareCommands(id c1, id c2, void *context);

@implementation DFCommandParser

NSString *_path;


- (id) initWithPath:(NSString *)path {
	_path = path;
	
	return self;
}


- (NSArray*) parse {
	
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	NSString *xml = [NSString stringWithContentsOfFile:_path];
	
	// create an xml doc obj from the pulled string
	NSXMLDocument *doc = [[NSXMLDocument alloc] initWithXMLString:xml options:NSXMLDocumentTidyXML error:NULL];
	
	// get the commands
	NSXMLElement *root = [doc rootElement];
	NSArray *commands = [root nodesForXPath:@"//command" error:NULL];
	
	// parse the xml
	NSMutableArray *return_commands = [[NSMutableArray alloc] init];
	
	int i=0;
	for(NSXMLElement *command in commands) {		
		
		fprintf(stdout,".");
		[return_commands addObject:[self handleCommand:command]];
		i++;
	}
	
	[pool drain];
	
	fprintf(stdout,"Sorting...");
	
	[return_commands sortUsingFunction:compareCommands context:nil];
	
	fprintf(stdout,"Done.\n");
	
	return return_commands;
}


-(DFCommand*) handleCommand:(NSXMLElement*) command {
	
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	DFCommand *c = [[DFCommand alloc] initWithName:[[command attributeForName:@"name"] stringValue]];
	
	c.description = [[[command nodesForXPath:[NSString stringWithFormat:@"%@%@",[command XPath],@"//description"] error:NULL] objectAtIndex:0] stringValue];
	c.returnsRows = [self boolifyString:[[[command nodesForXPath:[NSString stringWithFormat:@"%@%@",[command XPath],@"//returnsrows"] error:NULL] objectAtIndex:0] stringValue]];
	c.createsRows = [self boolifyString:[[[command nodesForXPath:[NSString stringWithFormat:@"%@%@",[command XPath],@"//createsrows"] error:NULL] objectAtIndex:0] stringValue]];
	
	// get the parameters
	NSArray *parameters = [command nodesForXPath:[NSString stringWithFormat:@"%@%@",[command XPath],@"//parameter"] error:NULL];
	for (NSXMLElement *parameter in parameters) {
		[c addParameter:[self handleParameter:parameter]];
	}
	
	// get the return parameters
	parameters = [command nodesForXPath:[NSString stringWithFormat:@"%@%@",[command XPath],@"//responsevalue"] error:NULL];
	for (NSXMLElement *parameter in parameters) {
		[c addReturnParameter:[self handleParameter:parameter]];
	}
	
	// get the row structure if there is one
	if ([[command nodesForXPath:[NSString stringWithFormat:@"%@%@",[command XPath],@"//responseline"] error:NULL] count] > 0) {
		parameters = [command nodesForXPath:[NSString stringWithFormat:@"%@%@",[command XPath],@"//responseline//value"] error:NULL];
		for (NSXMLElement *parameter in parameters) {
			[c addRowParameter:[self handleParameter:parameter]];
		}
	}
	
	[pool drain];
	
	return c;
}


-(DFParameter*) handleParameter:(NSXMLElement*) param {
	
	DFParameter *p = [[DFParameter alloc] init];
	
	p.name = [[param attributeForName:@"name"] stringValue];
	p.type = [DFParameter getTypeFromString:[[[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//type"] error:NULL] objectAtIndex:0] stringValue]];
	
	if ([[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//description"] error:NULL] count] > 0) {
		p.description = [[[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//description"] error:NULL] objectAtIndex:0] stringValue];
	} else { p.description = @""; }
	
	if ([[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//useinresponse"] error:NULL] count] > 0) {
		p.useInResponse = [self boolifyString:[[[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//useinresponse"] error:NULL] objectAtIndex:0] stringValue]];
	} else { p.useInResponse = false; }
	
	if ([[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//manditory"] error:NULL] count] > 0) {
		p.manditory = [self boolifyString:[[[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//manditory"] error:NULL] objectAtIndex:0] stringValue]];
	} else { p.manditory = false; }
	
	if ([[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//issearchnumber"] error:NULL] count] > 0L) {
		p.isSearchNumber = [self boolifyString:[[[param nodesForXPath:[NSString stringWithFormat:@"%@%@",[param XPath],@"//issearchnumber"] error:NULL] objectAtIndex:0] stringValue]];
	} else { p.isSearchNumber = false; }
	
	return p;
}

- (BOOL) boolifyString:(NSString*) string {
	if ([string caseInsensitiveCompare:@"true"] == NSOrderedSame) { return true; }
	else { return false; }
}

NSInteger compareCommands(id c1, id c2, void *context) {
	return [[c1 name] compare:[c2 name]];
}

@end
